package ch.quantasy.android.repetitive.service.implementation;

import java.util.concurrent.TimeUnit;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import ch.quantasy.android.repetitive.definition.RepeaterAction;
import ch.quantasy.android.repetitive.implementation.RepetitiveContextFacade;

/**
 * This class implements the possibility to process repetitive tasks via
 * {@link RepetitiveContextFacade}.
 * 
 * @author quantasy
 * 
 */
public abstract class ARepetitiveService extends Service implements
		RepeaterAction {
	public static final String START_REPETITION_EXTRA = "start_repetition_extra";

	public static void clearIntent(final Intent intent) {
		intent.removeExtra(ARepetitiveService.START_REPETITION_EXTRA);
	}

	public static void updateIntentStartStopRepetition(final Intent intent,
			final boolean start) {
		intent.putExtra(ARepetitiveService.START_REPETITION_EXTRA, start);
	}

	private RepetitiveContextFacade repeaterContext;

	public abstract void onStart(Intent intent);

	@Override
	public abstract void onRepeat();

	public abstract void onStop();

	public boolean isRunning() {
		return (this.repeaterContext != null)
				&& this.repeaterContext.isRunning();
	}

	public ARepetitiveService() {
		super();
		this.repeaterContext = new RepetitiveContextFacade(this);

	}

	@Override
	public void onDestroy() {
		if (this.repeaterContext == null) {
			return;
		}
		this.repeaterContext.stopTimedRepetition();
		this.repeaterContext.finalize();
		this.repeaterContext = null;
		super.onDestroy();

	}

	/**
	 * Start repeating the action- after the time specified
	 */
	protected void startTimedRepetition(final Intent intent) {
		if (this.repeaterContext == null) {
			return;
		}
		this.onStart(intent);
		this.repeaterContext.startTimedRepetition();
	}

	/**
	 * Stop repeating the action.
	 */
	protected void stopTimedRepetition() {
		if (this.repeaterContext == null) {
			return;
		}
		this.repeaterContext.stopTimedRepetition();
		this.onStop();
	}

	@Override
	public int onStartCommand(final Intent intent, final int flags,
			final int startId) {
		super.onStartCommand(intent, flags, startId);
		if ((intent == null) || (intent.getExtras() == null)) { // mark this as
																// non
			// sticky
			// Means: Don't
			// restart the
			// service if there
			// are no
			// pending intents.
			return Service.START_NOT_STICKY;
		}
		long interval = intent.getExtras().getInt("intervalInDays");
		interval = (interval * 24)
				+ intent.getExtras().getInt("intervalInHours");
		interval = (interval * 60)
				+ intent.getExtras().getInt("intervalInMinutes");
		interval = (interval * 60)
				+ intent.getExtras().getInt("intervalInSeconds");
		interval = (interval * 1000)
				+ intent.getExtras().getInt("intervalInMilliSeconds");
		if (interval > 0) {
			this.setUpdateInterval(interval, TimeUnit.MILLISECONDS);
		}
		if (intent.hasExtra(ARepetitiveService.START_REPETITION_EXTRA)) {
			final boolean start = intent.getExtras().getBoolean(
					ARepetitiveService.START_REPETITION_EXTRA);
			if (start) {
				this.startTimedRepetition(intent);
			} else {
				this.stopTimedRepetition();
			}
		}
		// mark this as non sticky
		// Means: Don't restart the service if there are no
		// pending intents.
		return Service.START_NOT_STICKY;
	}

	@Override
	public Context getContext() {
		return this;
	}

	public void setUpdateInterval(final long updateInterval, final TimeUnit unit) {
		if (this.repeaterContext == null) {
			return;
		}
		Log.d("ARepetitiveService", "updateInterval:" + updateInterval);
		this.repeaterContext.setUpdateInterval(updateInterval, unit);
	}

	public long getUpdateIntervalInMillis() {
		if (this.repeaterContext == null) {
			return Long.MAX_VALUE;
		}
		return this.repeaterContext.getUpdateIntervalInMillis();
	}

}